<template>
    <div class="static-container">
        <div style="border: 1px solid #ccc; padding: 5px">
            <div class="header">
                <el-form>
                    <el-form-item>
                        <el-select
                            name="执行ETL"
                            v-model="state.requestData.handleType"
                            placeholder=""
                            @change="handleClickETL(state.requestData.handleType, 'handleType')"
                            size="mini"
                            style="width: 120px"
                            :disabled="state.process.staticDataState.state != 'NO_CALCULATE'"
                        >
                            <el-option v-for="(value, key) in dataETL" :key="key" :label="key + ' ' + value" :value="key" :name="'calc' + key">
                            </el-option>
                        </el-select>
                    </el-form-item>
                    <el-form-item>
                        <!-- 选项为3时，历史计算：选择历史数据日期（只可选择有数据的日期） -->
                        <el-date-picker
                            v-model="tradeDate"
                            type="date"
                            placeholder="交易日期"
                            :disabled="['1', '2'].includes(state.requestData.handleType)"
                            size="mini"
                            style="width: 160px"
                            value-format="yyyyMMdd"
                            format="yyyy-MM-dd"
                        >
                            <!-- :key="tradeDateNumKey + 'tradeDateNumKey'" -->
                        </el-date-picker>
                    </el-form-item>
                    <el-form-item>
                        <el-input
                            name="条目编号"
                            placeholder="条目编号(支持','分隔)"
                            v-model="entryCodes"
                            size="mini"
                            style="width: 160px"
                            :disabled="state.process.staticDataState.state != 'NO_CALCULATE'"
                        ></el-input>
                    </el-form-item>
                </el-form>
                <div style="display: flex; flex-direction: column; margin-right: 10px">
                    <span
                        style="margin-bottom: 2px"
                        class="switch-style"
                        :class="state.requestData.needDynamicSync ? 'active-switch-style' : 'inactive-switch-style'"
                        v-if="state.requestData.handleType == '1'"
                    >
                        <el-switch
                            :disabled="state.requestData.handleType == '2' || state.process.staticDataState.state != 'NO_CALCULATE'"
                            v-model="state.requestData.needDynamicSync"
                            active-text="增量同步动态维度"
                            inactive-text="不增量同步动态维度"
                        >
                        </el-switch>
                        <!-- <span>是否增量同步动态维度</span> -->
                    </span>

                    <span
                        style="margin-bottom: 2px"
                        class="switch-style"
                        :class="state.requestData.needEntrySync ? 'active-switch-style' : 'inactive-switch-style'"
                        v-if="state.requestData.handleType == '1'"
                    >
                        <el-switch
                            :disabled="state.requestData.handleType == '2' || state.process.staticDataState.state != 'NO_CALCULATE'"
                            v-model="state.requestData.needEntrySync"
                            active-text="增量同步条目"
                            inactive-text="不增量同步条目"
                        >
                        </el-switch>
                        <!-- <span>是否增量同步条目</span> -->
                    </span>

                    <span
                        class="switch-style"
                        :class="{
                            'active-switch-style': state.requestData.importData,
                            'inactive-switch-style': !state.requestData.importData,
                            'handleType-value1': state.requestData.handleType == '2',
                        }"
                    >
                        <el-switch
                            :disabled="state.requestData.handleType == '1' || state.process.staticDataState.state != 'NO_CALCULATE'"
                            v-model="state.requestData.importData"
                            active-text="执行导数"
                            inactive-text="不执行导数"
                        >
                        </el-switch>
                    </span>
                </div>

                <el-button
                    name="计算"
                    size="mini"
                    type="primary"
                    v-authCode.show="B_0133"
                    @click="handleClickButton('start')"
                    :disabled="state.process.staticDataState.state != 'NO_CALCULATE'"
                >
                    <span
                        v-if="
                            state.process.staticDataState.state === 'BEFOR_ETL' ||
                                state.process.staticDataState.state === 'TOGETHER_ETL' ||
                                state.process.staticDataState.state === 'AFTER_ETL'
                        "
                        >正在计算</span
                    >
                    <span
                        v-else-if="
                            state.process.staticDataState.state === 'IN_CALCULATE' || state.process.staticDataState.state === 'CALULATE_FINISH'
                        "
                        >等待计算</span
                    >
                    <span v-else>开始计算</span>
                    <!-- {{ butName }} -->
                </el-button>
                <el-button
                    size="mini"
                    type="danger"
                    v-authCode.show="B_0134"
                    @click="handleClickButton('stop')"
                    :disabled="state.process.staticDataState.state == 'NO_CALCULATE'"
                >
                    停止
                </el-button>
                <el-button size="mini" type="primary" @click="calculateProhibitionDate" :disabled="!state.process.calculateProhibitionDate"
                    >重算连续违规天数</el-button
                >
            </div>
            <div class="operate">
                <el-radio-group
                    :value="
                        ['BEFOR_ETL', 'TOGETHER_ETL', 'AFTER_ETL'].includes(state.process.staticDataState.state)
                            ? 'DATA_INIT'
                            : state.process.staticDataState.state
                    "
                    finish-status="success"
                    disabled
                >
                    <el-radio label="NO_CALCULATE"
                        ><span :style="{ 'font-weight': state.process.staticDataState.state === 'NO_CALCULATE' ? '700' : '' }">未计算</span>
                    </el-radio>
                    <el-radio label="DATA_INIT"
                        ><span :style="{ 'font-weight': state.process.staticDataState.state === 'DATA_INIT' ? '700' : '' }">数据初始化</span>
                    </el-radio>
                    <el-radio label="IN_CALCULATE"
                        ><span :style="{ 'font-weight': state.process.staticDataState.state === 'IN_CALCULATE' ? '700' : '' }">计算中</span>
                    </el-radio>
                    <el-radio label="CALULATE_FINISH"
                        ><span :style="{ 'font-weight': state.process.staticDataState.state === 'CALULATE_FINISH' ? '700' : '' }"
                            >计算完成</span
                        ></el-radio
                    >
                </el-radio-group>
            </div>
        </div>
        <div class="main">
            <StaticCalcTimeChart :state="state" :key="renderCount + 'renderCount'"></StaticCalcTimeChart>
            <ProcessChart
                v-if="['IN_CALCULATE', 'CALULATE_FINISH'].includes(state.process.staticDataState.state)"
                :state="state"
                :renderCount="name.renderCount"
            ></ProcessChart>
            <!-- 具体条目 -->
            <CalcEntryTable v-if="['CALULATE_FINISH'].includes(state.process.staticDataState.state)" :state="state" />
        </div>
    </div>
</template>
<script lang="ts">
import { getConfigItem, GunDataGzip, StringToBase64 } from '@/utils/tools';
import { getUser } from '@/utils/user-util';
import { Component, Vue, Watch } from 'vue-property-decorator';
import ProcessChart from './risk-calc/process-chart.vue';
import StaticCalcTimeChart from './risk-calc/static-calc-time-chart.vue';
import CalcEntryTable from './risk-calc/calc-entry-table.vue';

@Component({
    name: 'RiskCalc',
    components: {
        StaticCalcTimeChart,
        ProcessChart,
        CalcEntryTable,
    },
})
export default class RiskCalc extends Vue {
    BASE_URL_WS = getConfigItem('BASE_URL_WS');

    private tradeDate: string = null; // 交易日期

    private tradeDateNumKey: number = -1; // 交易日期渲染Key

    private entryCodes: string = '';

    private TimeSendMessage = null;
    private butName: string = '开始计算';
    private butStart: string = 'stop';
    private showDis: boolean = false;

    // 请求参数
    private state = {
        requestData: {
            dataETL: false, //
            tradeDate: 0, // 交易日期
            entryCodes: '', // 条目编号
            importHistoryData: false, // 历史计算
            handleType: '1', // 处理方式
            needDynamicSync: false, // 是否增量同步动态维度
            needEntrySync: false, // 是否增量同步条目
            importData: false, // 是否执行导数
        },
        process: {
            staticDataState: {
                // 静态数据状态
                state: 'NO_CALCULATE',
                beforeEtlInits: [],
                beforeEtlInitFinishs: [],
                togetherEtlInits: [],
                togetherEtlInitFinishs: [],
                afterEtlInits: [],
                afterEtlInitFinishs: [],
            },
            calculateStartDate: '', // 开始计算时间
            calculateEndDate: '', // 结束计算时间
            state: 'NO_CALCULATE',
        },
        staticSystemDate: {
            '1': '',
            '3': [],
        },
    };

    name = {
        webSocket: null, // 状态
        renderCount: 1, // 表格渲染状态
    };

    // ETL导数
    dataETL = {
        '1': '不处理',
        '2': '执行ETL',
        // '3': '历史计算',
    };

    // 计算状态转义
    calcState = {
        NO_CALCULATE: '未计算',
        IN_CALCULATE: '计算中',
        CALULATE_FINISH: '计算完成',
        BEFOR_ETL: 'ETL之前',
        TOGETHER_ETL: 'ETL一起',
        AFTER_ETL: 'ETL之后',
    };

    mounted() {
        this.getSystemInitDate();
        this.getCalcStatus();
        this.initWebsocketConnect();
    }

    // 获取系统初始化日期
    private getSystemInitDate(): void {
        this.$axios.get('/baseInfomation/system/param').then((res: any) => {
            let staticSystemDate = {
                '1': '',
                '3': [],
            };
            if (res) {
                staticSystemDate['1'] = res.find(item => item.paramKey === '6').paramValue;
                staticSystemDate['3'] = (res.find(item => item.paramKey === '7').paramValue || '').split(',') || [];
                this.tradeDate = staticSystemDate['1'];
                // this.tradeDateNumKey++;
                this.state.staticSystemDate = staticSystemDate;
            } else {
                this.yh_message_error('获取系统初始化日期失败');
            }
        });
    }

    // @Watch('state', { immediate: true, deep: true })
    // watchState() {
    //     console.log(this.state.process.state);

    //     if (this.state.process.staticDataState.state == 'CALULATE_FINISH') {
    //         this.butName = '等待计算';
    //     } else if (this.state.process.staticDataState.state == 'DATA_INIT' || this.state.process.staticDataState.state == 'IN_CALCULATE') {
    //         this.butName = '正在计算';
    //     }
    // }

    // 查询计算引擎状态
    private getCalcStatus(): void {
        this.$axios.get('/dataEngine/static/status').then((returnValue: any) => {
            let prValue = this.changeDataFormat(JSON.parse(returnValue.process || '{}'));
            // console.log(returnValue.state, 'returnValue.state');
            // console.log(prValue, '开始的计算引擎状态');
            let res = returnValue.state;
            if (prValue.staticDataState.state !== res.engineStaticCalculateType) {
                prValue.staticDataState.state = res.engineStaticCalculateType;
            }
            let requestData = {
                dataETL: !!res.dataETL,
                tradeDate: res.tradeDate,
                entryCodes: res.entryCodes && res.entryCodes.length > 0 ? res.entryCodes.join(',') : '',
                importHistoryData: res.importHistoryData,
                handleType: '',
                needDynamicSync: res.needDynamicSync,
                needEntrySync: res.needEntrySync,
                importData: res.importData,
            };

            // this.tradeDate = res.tradeDate ? res.tradeDate.toString() : undefined;

            if (requestData.dataETL) {
                requestData.handleType = '2';
            } else if (requestData.importHistoryData) {
                requestData.handleType = '3';
            } else {
                requestData.handleType = '1';
            }
            this.state.process = prValue;
            if (res.engineStaticCalculateType !== 'NO_CALCULATE') {
                this.state.requestData = requestData;
                this.entryCodes = requestData.entryCodes;
            }
            // this.state.requestData = requestData;
            this.name.renderCount += 1;
        });
    }

    // 初始化websocket连接
    private initWebsocketConnect(): void {
        let Authentication = getUser().sessionId;
        let webSocket = new WebSocket(this.BASE_URL_WS + '/calcEngine/socket/' + StringToBase64(Authentication));

        webSocket.onopen = e => {
            this.$notify({
                type: 'success',
                message: '连接成功',
                title: '数据引擎初始化消息服务已连接',
            });
        };

        webSocket.onmessage = e => {
            let process = JSON.parse(GunDataGzip(e.data));
            console.info(process);
            this.state.process = process;
            this.name.renderCount += 1;
        };

        webSocket.onclose = e => {
            this.$notify({
                type: 'warning',
                message: '断开连接',
                title: '数据引擎初始化消息服务已断开',
            });
        };
        this.name.webSocket = webSocket;
        // 每隔1个小时发送一次消息 确保在使用nginx的情况下不会有断连的情况，同时约定nginx后台配置超时时间超过一个小时
        this.TimeSendMessage = setInterval(() => {
            try {
                webSocket.send('静态计算-发送WEBSOCKET心跳消息');
            } catch (e) {}
        }, 1000 * 60 * 60);
    }

    private beforeDestroy(): void {
        if (this.TimeSendMessage) {
            clearInterval(this.TimeSendMessage);
            this.TimeSendMessage = null;
        }
    }

    // 转换数据格式 针对为undinefund的情况
    private changeDataFormat(orgData: any): any {
        if (!orgData) {
            orgData = {};
        }
        if (!orgData.hasOwnProperty('staticDataState')) {
            Vue.set(orgData, 'staticDataState', {});
        }
        for (let value of [
            'beforeEtlInits',
            'beforeEtlInitFinishs',
            'togetherEtlInits',
            'togetherEtlInitFinishs',
            'afterEtlInits',
            'afterEtlInitFinishs',
        ]) {
            if (!orgData.staticDataState.hasOwnProperty(value)) {
                Vue.set(orgData.staticDataState, value, []);
            }
        }
        return orgData;
    }

    // 按钮事件
    private handleClickButton(action: string): void {
        this.butStart = action;
        if (action === 'start') {
            this.butName = '正在计算';
            let requestData = JSON.parse(JSON.stringify(this.state.requestData));
            // if (!this.tradeDate && requestData.handleType === '2') {
            //     // ETL时交易日期为空时默认给个0
            //     this.tradeDate = undefined;
            // }
            if (!this.tradeDate && ['1', '3'].includes(requestData.handleType)) {
                this.yh_message_warn('交易日期不可为空');
                return;
            }
            requestData.tradeDate = this.tradeDate ? parseInt(this.tradeDate) : 0;
            requestData.entryCodes = this.entryCodes ? this.entryCodes.split(',') : [];
            this.$axios.post('/dataEngine/static/calculate', requestData).then(res => {
                this.state.process['state'] = 'IN_CALCULATE';
                this.name.renderCount += 1;
            });
        } else if (action === 'stop') {
            this.$axios.get('/systemParam/getEtlState').then((res: any) => {
                if (res.paramValue == '1') {
                    this.$message.warning('导数中不能停止计算！');
                    return;
                }
                this.butName = '开始计算';
                this.$axios.get('/dataEngine/static/reset').then((res: any) => {
                    // this.state.process['state'] = 'NO_CALCULATE';
                    this.state.process.staticDataState.state = 'NO_CALCULATE';
                    this.name.renderCount += 1;
                });
            });
        }
    }

    // 跳过kettle事件
    private handleClickETL(value: string, filed: string): void {
        // console.log(value, filed, 'handleClickETL');
        let requestData = this.state.requestData;
        requestData[filed] = value;
        if (filed === 'handleType') {
            if (value === '1') {
                requestData.importHistoryData = false;
                requestData.dataETL = false;
                // requestData.tradeDate = parseInt(this.state.staticSystemDate['1']);
                // 不执行etl时，是否执行导数置为false并禁用
                requestData.importData = false;
                this.tradeDate = this.state.staticSystemDate['1'];
            } else if (value === '2') {
                requestData.importHistoryData = false;
                requestData.dataETL = true;
                this.tradeDate = undefined;
                // requestData.tradeDate = 0; // etl时，不显示时间
                // 执行etl时，是否增量同步动态维度和是否增量同步条目都置为false
                requestData.needDynamicSync = false;
                requestData.needEntrySync = false;
            } else if (value === '3') {
                requestData.importHistoryData = true;
                requestData.dataETL = false;
                this.tradeDate = undefined;
                // requestData.tradeDate = 0;
            }
        }
        // } else if (filed === 'tradeDate') {
        //     this.state.requestData.tradeDate = parseInt(this.tradeDate);
        // }
        // this.state.requestData = requestData;
    }

    private calculateProhibitionDate() {
        let entryCodes = this.entryCodes ? this.entryCodes.split(',') : [];
        //
        this.$axios.post('/dataEngine/static/calculateProhibitionDate', entryCodes).then(res => {});
        console.info();
    }
}
</script>
<style lang="scss" scoped>
.static-container {
    min-width: 1200px;
    height: 100%;
    padding: 15px;
    display: flex;
    flex-direction: column;
    .header {
        display: flex;
        align-items: center;
        .el-form {
            display: flex;
            .el-form-item {
                margin-bottom: 0px;
                margin-right: 10px;
            }
        }
        .switch-style {
            // margin-left: 5px;
            > span {
                margin-right: 10px;
                margin-left: 5px;
                // padding-bottom: 5px;
            }
            /deep/.el-switch__label--left,
            .is-active {
                width: 130px;
                text-align: right;
            }
        }
        .handleType-value1 {
            /deep/.el-switch__label--left,
            .is-active {
                width: 80px;
            }
        }
        .active-switch-style {
            color: #409eff;
        }
        .inactive-switch-style {
            color: #6d6f6d;
        }
    }
    .operate {
        width: fit-content;
        padding: 5px;

        .el-radio {
            cursor: no-drop;

            & /deep/ .el-radio__input {
                cursor: no-drop;
                .el-radio__inner {
                    cursor: no-drop;
                }
            }
        }
    }

    .main {
        margin-top: 10px;
        padding: 10px;
        border: 1px solid #d7d7d7;
        height: calc(100% - 115px);
        overflow: auto;
    }
}
/deep/ .el-icon-circle-check {
    color: rgb(135, 208, 104);
}
/deep/ .el-step__title {
    color: rgba(0, 0, 0, 0.65);
}
/deep/ .el-divider--horizontal {
    margin: 10px 0;
}
</style>
